from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import httpx
import logging
from pydantic import BaseModel
from typing import List, Union
import asyncio
import json

# 设置日志
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

app = FastAPI()

# 挂载静态文件目录
app.mount("/static", StaticFiles(directory="static"), name="static")

# 设置模板目录
templates = Jinja2Templates(directory="templates")

PLATFORMS = ["wy", "qq", "kw", "mg"]  # 移除了 'qi' 平台
SEARCH_API = "https://api.jkyai.top/API/hqyyid.php"
MUSIC_API = "https://api.jkyai.top/API/yyjhss.php"


class Song(BaseModel):
    type: str
    id: Union[str, int]
    name: str
    album: str
    artist: str
    pic_id: str

    def dict(self, *args, **kwargs):
        data = super().dict(*args, **kwargs)
        data['id'] = str(data['id'])  # 确保 id 总是字符串
        return data


class SearchResult(BaseModel):
    songs: List[Song]


async def fetch_data(url, params):
    logger.info(f"Fetching data from {url} with params: {params}")
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(url, params=params, headers={'User-Agent': 'Apifox/1.0.0 (https://apifox.com)'})
            response.raise_for_status()
            logger.debug(f"Response status code: {response.status_code}")
            logger.debug(f"Response content: {response.text}")
            try:
                return response.json()
            except json.JSONDecodeError as e:
                logger.error(f"JSON decode error: {e}")
                raise HTTPException(status_code=500, detail="Error decoding JSON response")
    except httpx.HTTPStatusError as e:
        logger.error(f"HTTP error occurred: {e}")
        raise HTTPException(status_code=e.response.status_code, detail=str(e))
    except httpx.RequestError as e:
        logger.error(f"Request error occurred: {e}")
        raise HTTPException(status_code=500, detail="An error occurred while fetching data")


@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request):
    logger.info("Rendering index page")
    return templates.TemplateResponse("index.html", {"request": request})


@app.get("/search")
async def search_music(name: str):
    logger.info(f"Searching for music with name: {name}")
    tasks = []
    for platform in PLATFORMS:
        params = {"name": name, "type": platform, "page": 1, "limit": 8}
        tasks.append(fetch_data(SEARCH_API, params))

    results = await asyncio.gather(*tasks, return_exceptions=True)

    all_songs = []
    for result in results:
        if isinstance(result, Exception):
            logger.warning(f"An error occurred during fetching data: {result}")
            continue
        if result.get("code") == 1 and "data" in result:
            all_songs.extend([Song(**song) for song in result["data"]])
        else:
            logger.warning(f"Unexpected result format: {result}")

    if not all_songs:
        logger.error("No songs found from any platform.")
        raise HTTPException(status_code=404, detail="No songs found.")

    logger.info(f"Found {len(all_songs)} songs")
    return SearchResult(songs=all_songs)


@app.get("/play")
async def play_music(id: str, type: str):
    logger.info(f"Fetching play information for song id: {id}, type: {type}")
    params = {"id": id, "type": type}
    try:
        result = await fetch_data(MUSIC_API, params)
    except Exception as e:
        logger.error(f"Error occurred while fetching play information: {e}")
        raise HTTPException(status_code=500, detail="An error occurred while fetching play information")

    if result.get("code") != 1 or "data" not in result:
        logger.error(f"Failed to fetch music data: {result}")
        raise HTTPException(status_code=404, detail="Music not found")

    song_data = result["data"]
    # 为了统一前端处理，确保返回的数据包含必要的字段
    response_data = {
        "name": song_data.get("name"),
        "artist": song_data.get("artist"),
        "url": song_data.get("url"),
        "pic": song_data.get("pic"),
        "lrc": song_data.get("lrc") or "",
        "id": id,
        "type": type
    }

    logger.info(f"Successfully fetched play information for song: {song_data['name']}")
    return response_data


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=1688)
